package com.deuwise.system.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.deuwise.common.base.Tree;
import com.deuwise.common.utils.R;
import com.deuwise.common.utils.Result;
import com.deuwise.common.validator.ValidatorUtils;
import com.deuwise.common.validator.group.AddGroup;
import com.deuwise.common.validator.group.UpdateGroup;
import com.deuwise.system.entity.DictDo;
import com.deuwise.system.entity.DictDo;
import com.deuwise.system.service.DictDoService;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 *@author deuwise
 *@date 2018-11-12 16:05:19
 */
@Api(tags = "数字字典模块", description = "数字字典模块")
@RequestMapping("api/dict")
@RestController()
public class DictDoController extends AbstractController {
    @Autowired
    private DictDoService dictDoService;

    @ApiOperation(value = "新增数字字典")
    @PostMapping()
    @RequiresPermissions("sys:dict:save")
    public R insertDict(@RequestBody DictDo dictDo){
        ValidatorUtils.validateEntity(dictDo, AddGroup.class);
        boolean isSuccess = false;
        if(null == dictDo){
            return R.error(200,"新增数字字典失败，请稍后再试!");
        }
        int count = dictDoService.queryByName(dictDo.getName(), dictDo);
        if (count > 0) {
            return R.error(200, "字典名称不能重复");
        }
        dictDo.setCreateBy(getUserId());
        dictDo.setCreateDate(new Date());
        dictDo.setUpdateBy(getUserId());
        dictDo.setUpdateDate(new Date());
        isSuccess = dictDoService.insertOrUpdate(dictDo);
        if (isSuccess) {
            return R.ok(dictDo);
        } else {
            return R.error(200,"新增数字字典失败，请稍后再试!");
        }
    }
    /**
     * 数字字典信息
     */
    @ApiOperation("数字字典信息")
    @GetMapping("/{dictId}")
    @RequiresPermissions("sys:dict:info")
    public Result<DictDo> info(@PathVariable("dictId") String dictId){
        DictDo dictDo = dictDoService.selectById(dictId);
        return  Result.ok(dictDo);
    }

    @ApiOperation("修改数字字典")
    @PutMapping("")
    @RequiresPermissions("sys:dict:update")
    public R update(@RequestBody DictDo dictDo){
        ValidatorUtils.validateEntity(dictDo, UpdateGroup.class);
        dictDo.setUpdateBy(getUserId());
        dictDo.setUpdateDate(new Date());
        int count = dictDoService.queryByName(dictDo.getName(), dictDo);
        if (count > 0) {
            return R.error(200, "字典名称不能重复");
        }
        dictDoService.updateById(dictDo);

        return R.ok();
    }
    @ApiOperation(value = "获取list", notes = "获取list")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentPage", value = "开始页数", defaultValue = "1", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页多少条", defaultValue = "15", dataType = "int", paramType = "query")})
    public Result<Page<DictDo>> list(DictDo dictDo){
        Wrapper<DictDo> wrapper = new EntityWrapper<DictDo>().orderBy("order_num", false);
        if(dictDo!=null){
            if(StringUtils.isNotBlank(dictDo.getName())){
                wrapper.like("name",dictDo.getName());
            }
            if(StringUtils.isNotBlank(dictDo.getParentId())){
                wrapper.eq("parent_id",dictDo.getParentId());
            }

            if(StringUtils.isNotBlank(dictDo.getType())){
                wrapper.eq("type",dictDo.getType());
            }
        }
        wrapper.orderBy("create_date",false);
        Page<DictDo> sysDictPage = dictDoService.selectPage(getPage(DictDo.class),wrapper);
        return Result.ok(sysDictPage);
    }

    @ApiOperation("获取字典树")
    @RequestMapping(value = "/tree", method = RequestMethod.GET)
    @RequiresPermissions("sys:dict:list")
    public Result<List<Tree<DictDo>>> tree(DictDo dictDo){
       /* Wrapper<DictDo> wrapper = new EntityWrapper<DictDo>().orderBy("order_num", false);
        if(dictDo!=null){
            if(StringUtils.isNotBlank(dictDo.getName())){
                wrapper.like("name",dictDo.getName());
            }
            if(StringUtils.isNotBlank(dictDo.getParentId())){
                wrapper.eq("parent_id",dictDo.getParentId());
            }

            if(StringUtils.isNotBlank(dictDo.getType())){
                wrapper.eq("type",dictDo.getType());
            }
        }
        wrapper.orderBy("create_date",false);
        List<DictDo> sysDictPage = dictDoService.selectList(wrapper);
        List<Tree<DictDo>> trees = new ArrayList<Tree<DictDo>>();
        //判断是否存在父节点
        List<String> parentIds=new ArrayList<>();
        for(DictDo dictDo1 : sysDictPage){
            Tree<DictDo> tree = new Tree<DictDo>();
            DictDo parentMenuEntity = dictDoService.selectById(dictDo1.getParentId());
            if(parentMenuEntity != null){
                dictDo1.setParentName(parentMenuEntity.getName());
            }
            if(sysDictPage.stream().filter(f->f.getId().equals(dictDo1.getParentId())).count()<=0){
                if(!parentIds.contains(dictDo1.getParentId())) {
                    parentIds.add(dictDo1.getParentId());
                    Tree<DictDo> parent = new Tree<DictDo>();
                    parent.setId(dictDo1.getParentId());
                    parent.setParentId("0");
                    if(parentMenuEntity != null) {
                        parent.setText(parentMenuEntity.getName());
                    }
                    Map<String, Object> map=new HashMap<>(16);
                    map.put("value","");
                    map.put("type","");
                    map.put("parentName","");
                    map.put("orderNum","");
                    map.put("remarks","");
                    parent.setAttributes(map);
                    trees.add(parent);
                }

            }
            tree.setId(dictDo1.getId());
            tree.setParentId(dictDo1.getParentId());
            tree.setText(dictDo1.getName());
            Map<String, Object> map=new HashMap<>(16);
            map.put("value",dictDo1.getValue());
            map.put("type",dictDo1.getType());
            map.put("parentName",dictDo1.getParentName());
            map.put("orderNum",dictDo1.getOrderNum());
            map.put("remarks",dictDo1.getRemarks());
            tree.setAttributes(map);
            trees.add(tree);
        }
        Tree<DictDo> dictDoTree= BuildTree.build(trees);
        List<Tree<DictDo>> treeList=new ArrayList<>();
        if(dictDoTree.getChildren()!=null){
            treeList=dictDoTree.getChildren();
        }else{
            treeList.add(dictDoTree);
        }*/
        Tree<DictDo> tree = new Tree<>();
        tree = dictDoService.getTree(dictDo);
        List<Tree<DictDo>> treeList=new ArrayList<>();
        if(tree.getChildren()!=null){
            treeList=tree.getChildren();
        }else{
            treeList.add(tree);
        }
        return Result.ok(treeList);
    }

    @GetMapping("/treeTable")
    @ResponseBody
    @ApiOperation("查询字典树形数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "标签名", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "类型", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "description", value = "描述", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "remarks", value = "备注信息", dataType = "String", paramType = "query")})
    public R treeTable(String name,String type, String description, String remarks) {
        List<Tree<DictDo>> treeList=new ArrayList<>();
        // 查询所有字典
        List<String> idList=new ArrayList<>();
        Wrapper<DictDo> wrapNameList = new EntityWrapper<DictDo>();
        if(StringUtils.isNotBlank(name)){
            wrapNameList.like("name", name);
            List<DictDo> list = dictDoService.selectList(wrapNameList);
            idList=list.stream().map(f->f.getParentId()).collect(Collectors.toList());
            List<String> idList2=list.stream().map(f->f.getId()).collect(Collectors.toList());
            idList.addAll(idList2);
        }

        Wrapper<DictDo> wrapperParent = new EntityWrapper<DictDo>();
        wrapperParent.eq("parent_id", "0");
        if(idList!=null&&idList.size()>0){
            wrapperParent.in("id", idList);
        }

        // 查询父级
        List<DictDo> parentList = dictDoService.selectList(wrapperParent);

        Wrapper<DictDo> wrapper = new EntityWrapper<DictDo>();
        wrapper.addFilter("parent_id != '0'");
        if(StringUtils.isNotBlank(name)){
            wrapper.like("name", name);
        }
        if(StringUtils.isNotBlank(type)){
            wrapper.like("type", type);
        }
        if(StringUtils.isNotBlank(description)){
            wrapper.like("description", description);
        }
        if(StringUtils.isNotBlank(remarks)){
            wrapper.like("remarks", remarks);
        }
        List<DictDo> list = dictDoService.selectList(wrapper);
        parentList.addAll(list);
        for(DictDo dictDo : parentList){
            if("0".equals(dictDo.getParentId())){
                Tree<DictDo> tree = new Tree<>();
                tree.setId(dictDo.getId());
                tree.setParentId(dictDo.getParentId());
                tree.setText(dictDo.getName());
                Map<String, Object> state = new HashMap<>(16);
                state.put("opened", false);
                tree.setState(state);
                /*组装属性信息*/
                Map<String, Object> map=new HashMap<>(16);
                map.put("name", dictDo.getName());
                map.put("value", dictDo.getValue());
                map.put("type", dictDo.getType());
                map.put("description", dictDo.getDescription());
                map.put("orderNum", dictDo.getOrderNum());
                map.put("parentId", dictDo.getParentId());
                map.put("parentName", dictDo.getParentName());
                map.put("createDate", dictDo.getCreateDate());
                map.put("remarks", dictDo.getRemarks());
                tree.setAttributes(map);
                Tree<DictDo> tree1 = findChild(tree,list);
                if(0 < tree1.getChildren().size()){
                    treeList.add(tree1);
                }else if(-1 < tree1.getText().indexOf(name) && StringUtils.isNotBlank(name)){
                    //搜索条件包含父节点
                    treeList.add(tree1);
                }else if(0 == tree1.getChildren().size() && StringUtils.isBlank(name)){
                    // 显示根没有子节点，并且不是通过条件搜索得到
                    treeList.add(tree1);
                }
            }
        }
        return R.ok(treeList);
    }


    @ApiOperation("删除字典")
    @DeleteMapping("/{id}")
    @RequiresPermissions("sys:dict:delete")
    public R delete(@PathVariable("id") String id){


        dictDoService.deleteById(id);

        return R.ok();
    }
    @ApiOperation(value = "批量删除记录")
    @RequestMapping(value = "/deleteSelect", method = RequestMethod.POST)
    @RequiresPermissions("sys:dict:delete")
    public R deleteSelect(@ApiParam(value = "ids集合",name = "ids",required = true) @RequestParam String[] ids){
        try {
            if (ids != null && ids.length > 0) {
                dictDoService.deleteBatchIds(Arrays.asList(ids));

            }
        }catch (Exception ex){
            return  R.error("删除失败");
        }
        return  R.ok();
    }

    static Tree<DictDo> findChild(Tree<DictDo> tree, List<DictDo> list){
        try{
            for(DictDo dictDo : list){
                if(dictDo.getParentId().equals(tree.getId())){
                    Tree<DictDo> childrenTree = new Tree<>();
                    if(0 == tree.getChildren().size()){
                        tree.setChildren(new ArrayList<Tree<DictDo>>());
                    }
                    /*组装属性信息*/
                    Map<String, Object> map=new HashMap<>(16);
                    map.put("name", dictDo.getName());
                    map.put("value", dictDo.getValue());
                    map.put("type", dictDo.getType());
                    map.put("description", dictDo.getDescription());
                    map.put("orderNum", dictDo.getOrderNum());
                    map.put("parentId", dictDo.getParentId());
                    map.put("parentName", dictDo.getParentName());
                    map.put("createDate", dictDo.getCreateDate());
                    map.put("remarks", dictDo.getRemarks());
                    childrenTree.setId(dictDo.getId());
                    childrenTree.setText(dictDo.getName());
                    childrenTree.setParentId(dictDo.getParentId());
                    childrenTree.setAttributes(map);
                    tree.getChildren().add(childrenTree);
                    findChild(childrenTree,list);
                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }

        return tree;
    }
}